Skip to content

Simultaneous-edit protection for workspace files#1949

Merged
AaronPlave merged 8 commits into
developfrom
feat/simultaneous-workspace-file-edit-protection
Jul 9, 2026
Merged

Simultaneous-edit protection for workspace files#1949
AaronPlave merged 8 commits into
developfrom
feat/simultaneous-workspace-file-edit-protection

Conversation

@AaronPlave

@AaronPlave AaronPlave commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

___REQUIRES_AERIE_PR___="1836"

Summary

Implements simultaneous edit protection for workspace files. Closes #1789 and will make a followup issue for auto-save. Previously, two people editing the same workspace file could silently overwrite each other. Now, if a file changed since you opened it, saving shows you a diff in a modal and lets you choose which version to keep (yours, theirs, or cancel). This PR also fixes a related bug where "read-only" files could still be edited through the syntax highlighting diagnostic auto-fix buttons and the right tab command panel inputs.

Backend PR here: NASA-AMMOS/plandev#1836, details the approach for edit protections using HTTP ETag and If-Match headers.

Details

  • Each open file remembers the ETag it was loaded with and sends it on save back to the server so the server can reject the save if the file changed underneath.
  • When the server rejects, a modal re-fetches the file and shows a read-only side-by-side diff (built on
    @codemirror/merge). The modal handles the file being changed, deleted/moved, or temporarily unreachable — the last one never offers a destructive option.
  • Read-only fix: the editor's read-only flag only blocks typing, so things like lint "quick fixes" and the command-panel form could still change the file. A guard now blocks those too, and the command panel's inputs are disabled when read-only.
  • Command-argument inputs received proper accessible labels in support of e2e testing and general accessibility.

Visible UX Changes

  • Saving a file someone else changed → a Theirs / Mine diff with Keep theirs, Keep Mine,
    or Keep editing. Keeping theirs is undoable (cmd/ctrl-z restores your discarded edits).
  • File was deleted or moved → a modal with Recreate or Discard.
  • Couldn't load the latest version → a Retry prompt (nothing destructive).
  • Selected Command panel's inputs are now greyed out while a file is in read-only mode.

Verification

  • New unit tests:
    • src/stores/activeDocument.test.ts
    • src/utilities/codemirror/readOnly.test.ts
    • src/utilities/requests.test.ts
  • Updated unit test: src/utilities/workspaces.test.ts
  • New e2e test: e2e-tests/tests/workspace-edit-protection.ts
  • Updated e2e test: e2e-tests/tests/workspace.test.ts

@AaronPlave AaronPlave self-assigned this Jun 12, 2026
@AaronPlave AaronPlave added the feature New feature or request label Jun 12, 2026
@AaronPlave AaronPlave changed the title simultaneous-edit protection for workspace files Simultaneous-edit protection for workspace files Jun 12, 2026
@AaronPlave AaronPlave marked this pull request as ready for review June 15, 2026 18:42
@AaronPlave AaronPlave requested review from a team as code owners June 15, 2026 18:42

@dandelany dandelany left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested locally with @AaronPlave and this is working well. A few notes below - mostly handling edge cases and small style things.

Comment thread src/utilities/requests.ts Outdated
Comment thread src/stores/activeDocument.ts Outdated
Comment thread src/routes/workspaces/[workspaceId]/+page.svelte Outdated
Comment thread src/components/modals/WorkspaceSaveConflictModal.svelte Outdated
Comment thread src/components/modals/WorkspaceSaveConflictModal.svelte Outdated
Comment thread src/components/modals/WorkspaceSaveConflictModal.svelte Outdated
Comment thread src/components/modals/WorkspaceSaveConflictModal.svelte

@dandelany dandelany left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-tested latest changes with @AaronPlave - all works as expected, ready to merge!

…lict modal

- Rename reqWorkspaceWithMeta -> reqWorkspaceWithEtag (+ return type) to avoid
  confusion with reqWorkspaceMetadata
- Rename the opaque "token" vocabulary to "etag" across the activeDocument store
  (baseToken -> baseEtag), modal resolution, effects, and consumers
- Redesign WorkspaceSaveConflictModal: gray footer bar with white "Keep theirs /
  Keep mine" buttons, per-action consequence sublines, and a "Keep editing"
  escape; unify the conflict / deleted / load-error footers
- Show an "N changed lines" summary in the diff header (emitted from the diff viewer)
- Deleted variant: destructive text cue on "Discard & close" + "Recreate file",
  each with a consequence subline
- Re-fetch the latest server version when the user picks "Keep theirs" so it never
  applies a stale snapshot from when the modal opened
- Make "Keep theirs" undoable: rebaseContent() on both editors records the rebase
  in the undo history so Cmd-Z restores the discarded edits
- Add e2e coverage for the undo behavior; update conflict fixture selectors/labels
@AaronPlave AaronPlave force-pushed the feat/simultaneous-workspace-file-edit-protection branch from 42cdf53 to a093d3f Compare July 9, 2026 00:44
@sonarqubecloud

sonarqubecloud Bot commented Jul 9, 2026

Copy link
Copy Markdown

@AaronPlave AaronPlave merged commit b75f68a into develop Jul 9, 2026
11 of 13 checks passed
@AaronPlave AaronPlave deleted the feat/simultaneous-workspace-file-edit-protection branch July 9, 2026 18:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Phoenix: Add protections against sequence edits from multiple users

2 participants